package cate.game.play.part;

import cate.common.table.d.GDFight;
import cate.game.play.config.AllPlayCfg;
import cate.game.play.config.destiny.DestinyCfg;
import cate.game.play.fighter.Fighter;
import cate.game.play.fighter.HallowFighter;
import cate.game.play.fighter.HeroFighter;
import cate.game.play.fighter.PetFighter;
import cate.game.play.proce.action.ctx.TimeActionCtx;
import cate.game.play.proce.move.MoveCtx;
import cate.game.play.proce.play.PlayCtx;
import cate.game.play.proce.round.RoundCtx;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;


@NoteClass("相互PK的队伍")
public class TeamVS {

	@NoteField("队伍A")
	public FightTeam a;

	@NoteField("队伍B")
	public FightTeam b;


	/**
	 * 获取场上的英雄(英雄 召唤物)
	 * @return
	 */
	@JsonIgnore
	public List<Fighter> getAreaFighters() {
		List<Fighter> fighters = new ArrayList<>();
		fighters.addAll(a.getAreaFighters());
		fighters.addAll(b.getAreaFighters());
		return fighters;
	}

	@JsonIgnore
	public List<Fighter> getAllAreaFighters(){
		List<Fighter> fighters = new ArrayList<>();
		fighters.addAll(a.getAllAreaFighters());
		fighters.addAll(b.getAllAreaFighters());
		return fighters;
	}

	public TeamVS() {
	}

	public TeamVS(FightTeam a, FightTeam b) {
		this.a = a;
		this.b = b;
	}

	@JsonIgnore
	public List<HallowFighter> getHallowsBySpeed() {
		List<HallowFighter> hallows = new ArrayList<>();
		if (a.status.beginTotalSpeed >= b.status.beginTotalSpeed) {
			hallows.addAll(a.getHallows());
			hallows.addAll(b.getHallows());
		} else {
			hallows.addAll(b.getHallows());
			hallows.addAll(a.getHallows());
		}
		return hallows;
	}

	@JsonIgnore
	public List<PetFighter> getPetsBySpeed() {
		List<PetFighter> allPets = new ArrayList<>();
		if (a.status.beginTotalSpeed >= b.status.beginTotalSpeed) {
			allPets.addAll(a.getPets());
			allPets.addAll(b.getPets());
		} else {
			allPets.addAll(b.getPets());
			allPets.addAll(a.getPets());
		}
		return allPets;
	}


	/** 双方PK是否结束 任一方死光就是结束 */
	@JsonIgnore
	public boolean isOver() {
		boolean lossA = isLoss(GDFight.Team.A); // A队输了
		boolean lossB = isLoss(GDFight.Team.B); // B队输了
		return lossA || lossB;
	}

	@JsonIgnore
	private boolean isLoss(byte team) {
		FightTeam fightTeam = getTeam(team);
		return fightTeam == null || fightTeam.isLoss();
	}

	public FightTeam getTeam(byte team) {
		if (GDFight.Team.A == team) {
			return a;
		} else  {
			return b;
		}
	}

	public FightTeam getEnemyTeam(byte team) {
		if (GDFight.Team.A == team) {
			return b;
		} else  {
			return a;
		}
	}


	/**
	 * 战斗开始前的处理
	 * @param play
	 */
	public void beforeFight(PlayCtx play) {
		handleDestiny(play.config);
		a.beforeFight(play);
		b.beforeFight(play);
	}

	/**
	 * 战斗开始时
	 * @param play
	 */
	public void onFightBegin(PlayCtx play) {
		a.onFightBegin(play);
		b.onFightBegin(play);
	}

	private void handleDestiny(AllPlayCfg config) {
		int totalA = 0;
		int totalB = 0;
		for (HeroFighter allHero : a.getAllHero()) {
			totalA += Math.min(allHero.star, 14);
		}
		for (HeroFighter allHero : b.getAllHero()) {
			totalB += Math.min(allHero.star, 14);
		}
		DestinyCfg cfg = config.destiny.find(Math.abs(totalA - totalB));
		if (cfg != null && cfg.row.buff > 0) {
			FightTeam targetTeam = totalA >= totalB ? a : b;
			targetTeam.addTeamBuff(cfg.row.buff);
		}
	}

	/** 获取胜利队伍 */
	@JsonIgnore
	public byte getWinnerTeam() {
		boolean lossA = isLoss(GDFight.Team.A); // A队输了
		boolean lossB = isLoss(GDFight.Team.B); // B队输了
		if (!lossA && !lossB) {
			return GDFight.Team.NONE;
		}
		if (lossA && lossB) {
			return GDFight.Team.NONE;
		}
		if (lossA) {
			return GDFight.Team.B;
		} else {
			return GDFight.Team.A;
		}
	}

	public TeamVS copy(){
		TeamVS cp = new TeamVS();
		cp.a = this.a.copy();
		cp.b = this.b.copy();
		return cp;
	}

	public void onRoundBegin(RoundCtx round) {
		TimeActionCtx timeAction = round.buildTimeAction();
		forAreaFighters(f -> f.handleFirstEnter(timeAction));
		forAreaFighters(f -> f.skill.forHandlers(h -> h.beforeRoundBegin(timeAction)));
		forAreaFighters(f -> f.skill.forHandlers(h -> h.onRoundBegin(timeAction)));
	}

	public void onRoundEnd(RoundCtx round){
		TimeActionCtx timeAction = round.buildTimeAction();
		forAreaFighters(f -> f.skill.forHandlers(h -> h.onRoundEnd(timeAction)));
	}


	public void onMoveDone(MoveCtx move) {
		TimeActionCtx action = move.buildTimeAction();
		forAreaFighters(f -> {
			f.skill.forHandlers(h -> h.onMoveDone(move, action));
			f.buff.forHandlers(h -> h.onMoveDone(move, action));
			if (f.status.isMarkDead()) {
				f.status.setMarkDead(false);
				f.handleImmediateRebirth(action);
			}
		});
		forAreaFighters(f -> {
			f.skill.forHandlers(h -> h.afterMoveDone(move));
		});
	}

	/**
	 * 所有场上的fighter
	 * @param consumer
	 */
	public void forAreaFighters(Consumer<Fighter> consumer) {
		getAllAreaFighters().forEach(consumer);
	}


}
